import cv2
import numpy as np

# 读取图像
img = cv2.imread("img.png")
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 转换为 RGB

# 定义圆形内部和外部的目标颜色范围
lower_inner = np.array([85-10, 98-10, 98-10])  # 允许的颜色下限
upper_inner = np.array([85+10, 98+10, 98+10])  # 允许的颜色上限

lower_edge = np.array([55-10, 63-10, 65-10])  # 边缘的颜色下限
upper_edge = np.array([55+10, 63+10, 65+10])  # 边缘的颜色上限

# 筛选出符合颜色范围的区域（内部和外部的颜色）
mask_inner = cv2.inRange(img_rgb, lower_inner, upper_inner)
mask_edge = cv2.inRange(img_rgb, lower_edge, upper_edge)

# 合并内外颜色区域
mask_combined = cv2.bitwise_and(mask_inner, mask_edge)

# 使用高斯模糊减少噪声
blurred = cv2.GaussianBlur(mask_combined, (15, 15), 0)

# 使用Canny边缘检测来找出边缘
edges = cv2.Canny(blurred, 50, 150)

# 使用霍夫圆变换检测圆形
circles = cv2.HoughCircles(
    edges,  # 使用边缘检测图像
    cv2.HOUGH_GRADIENT, dp=1.2, minDist=30, param1=50, param2=30, minRadius=100, maxRadius=150
)

# 如果找到圆形
if circles is not None:
    circles = np.round(circles[0, :]).astype("int")  # 转为整数坐标和半径
    for (x, y, r) in circles:
        # 获取圆心处的颜色
        center_color = img_rgb[y, x]

        # 获取圆形边缘的颜色（选择圆周上的一个点，比如在圆的上方）
        edge_color = img_rgb[y - r, x]  # 圆的上方的一个点

        # 计算圆心和边缘的颜色差异
        color_diff = np.linalg.norm(center_color - edge_color)

        # 如果圆心与边缘的颜色差异大于某个阈值（说明边缘明显与内外不同），则认为该圆形符合条件
        if color_diff > 20:  # 颜色差异的阈值
            # 绘制符合条件的圆形和圆心
            cv2.circle(img, (x, y), r, (0, 255, 0), 4)  # 绘制圆形
            cv2.rectangle(img, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)  # 绘制圆心

# 显示结果图像
cv2.imshow("Detected Circles", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
